﻿using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
using ruleEngineDemo.engine.factory.product;
using ruleEngineDemo.engine.viewmodel;
using RulesEngine.Models;
using System.Dynamic;

namespace ruleEngineDemo.engine.rulesengine.product
{
    /// <summary>
    /// json rules
    /// </summary>
    public class JsonRules : IJsonRules
    {
        /// <summary>
        /// 执行rules
        /// </summary>
        /// <returns></returns>
        public RulesResult Run()
        {
            var basicInfo = "{\"name\": \"hello\",\"email\": \"abcy@xyz.com\",\"creditHistory\": \"good\",\"country\": \"canada\",\"loyaltyFactor\": 3,\"totalPurchasesToDate\": 10000}";
            var orderInfo = "{\"totalOrders\": 5,\"recurringItems\": 2}";
            var telemetryInfo = "{\"noOfVisitsPerMonth\": 10,\"percentageOfBuyingToVisit\": 15}";

            var converter = new ExpandoObjectConverter();

            dynamic input1 = JsonConvert.DeserializeObject<ExpandoObject>(basicInfo, converter);
            dynamic input2 = JsonConvert.DeserializeObject<ExpandoObject>(orderInfo, converter);
            dynamic input3 = JsonConvert.DeserializeObject<ExpandoObject>(telemetryInfo, converter);

            var inputs = new dynamic[]
                {
                    input1,
                    input2,
                    input3
                };

            var files = Directory.GetFiles(Directory.GetCurrentDirectory(), "Discount.json", SearchOption.AllDirectories);
            if (files == null || files.Length == 0)
                throw new Exception("Rules not found.");

            var fileData = File.ReadAllText(files[0]);
            var workflow = JsonConvert.DeserializeObject<List<Workflow>>(fileData);

            var bre = new RulesEngine.RulesEngine(workflow.ToArray(), null);

            List<RuleResultTree> resultList = bre.ExecuteAllRulesAsync("Discount", inputs).Result;

            RulesResult rRt = new RulesResult
            {
                IsPass = true,
                Errors = new List<string>()
            };
            foreach (var item in resultList)
            {
                if (item.IsSuccess == false)
                {
                    rRt.IsPass = false;
                    rRt.Errors.Add($"Failed: {item.Rule.RuleName}");
                }
            }
            return rRt;
        }
    }
}
